using System;
using System.ComponentModel;
using System.Windows.Forms;
using System.Runtime.InteropServices; // Needed for DLLImport

namespace ErkerTech.DeltaScope.View.Common
{
    public class BaseControl : UserControl
    {
        [DllImport("User32", CharSet=CharSet.Auto)]
        private static extern int GetWindowLong(IntPtr hWnd, int Index);

        [DllImport("User32", CharSet=CharSet.Auto)]
        private static extern int SetWindowLong(IntPtr hWnd, int Index, int Value);

        [DllImport("User32", ExactSpelling=true)]
        private static extern int SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, 
                                               int x, int y, int cx, int cy, uint uFlags);

        #region Constants
        // These constants were taken from WinUser.h
        private const int WS_BORDER  = 0x00800000;
        private const int WS_EX_CLIENTEDGE = 0x00000200;

        // Constants from WinUser.h
        const int GWL_STYLE = -16;
        const int GWL_EXSTYLE = -20;

        const uint SWP_NOSIZE   = 0x0001;
        const uint SWP_NOMOVE   = 0x0002;
        const uint SWP_NOZORDER   = 0x0004;
        const uint SWP_NOACTIVATE  = 0x0010;
        const uint SWP_FRAMECHANGED  = 0x0020;
        const uint SWP_NOOWNERZORDER = 0x0200;

        #endregion

        #region Private Declarations
        private Container components;
        private BorderStyle borderStyle = BorderStyle.None;
        #endregion

        #region Constructor
        public BaseControl()
        {
            // This call is required by the Windows.Forms Form Designer.
            InitializeComponent();

            SetStyle(ControlStyles.ContainerControl, false);
            SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint, true);
        }
        #endregion

        #region Generic .NET code
        protected override void Dispose( bool disposing )
        {
            if( disposing )
            {
                if(components != null)
                {
                    components.Dispose();
                }
            }
            base.Dispose( disposing );
        }
		
        #region Component Designer generated code
        /// <summary> 
        /// Required method for Designer support - do not modify 
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            components = new System.ComponentModel.Container();
        }
        #endregion
        #endregion

        #region Override Events
        protected override void OnResize(EventArgs e)
        {
            base.OnResize (e);
            //if ((this.Site == null) || (this.Site.DesignMode == false)) this.Invalidate(true);
            Invalidate();
        }
        #endregion

        #region Private Methods
        // Convert borderStyle to Style and ExStyle values for Win32
        private void BorderStyleToWindowStyle(ref int style, ref int exStyle)
        {
            style &= ~WS_BORDER;
            exStyle &= ~WS_EX_CLIENTEDGE;
            switch(borderStyle)
            {
                case BorderStyle.Fixed3D:
                    exStyle |= WS_EX_CLIENTEDGE;
                    break;

                case BorderStyle.FixedSingle:
                    style |= WS_BORDER;
                    break;

                case BorderStyle.None:
                    // No border style values
                    break;
            }
        }

        protected override CreateParams CreateParams
        {
            get
            {
                // Get the default values from the base class
                CreateParams p = base.CreateParams;

                // Store the Style and ExStyle values
                int style = p.Style;
                int exStyle = p.ExStyle;

                // Modify the values to match the desired border style
                BorderStyleToWindowStyle(ref style, ref exStyle);

                // Store the results back in the CreateParams class
                p.Style = style;
                p.ExStyle = exStyle;
                return p;
            }
        }
        #endregion

        #region Public Properties
        /// <summary>
        /// Gets or sets the border style of the tree view control.
        /// </summary>
        [Category("Appearance")]
        [Description ("Border style of the control")]
        [DefaultValue(typeof(BorderStyle), "None")]
        public new BorderStyle BorderStyle
        {
            get {return borderStyle;}
            set
            {
                borderStyle = value;
                // Get Styles using Win32 calls
                int style = GetWindowLong(Handle, GWL_STYLE);
                int exStyle = GetWindowLong(Handle, GWL_EXSTYLE);

                // Modify Styles to match the selected border style
                BorderStyleToWindowStyle(ref style, ref exStyle);

                // Set Styles using Win32 calls
                SetWindowLong(Handle, GWL_STYLE, style);
                SetWindowLong(Handle, GWL_EXSTYLE, exStyle);

                // Tell Windows that the frame changed
                SetWindowPos(Handle, IntPtr.Zero, 0, 0, 0, 0,
                             SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE |
                             SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_FRAMECHANGED);
            }
        }
        #endregion
    }
}